package com.jlu.drsmog;

import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;

public class CropActivity extends AppCompatActivity {

    final int READ_REQUEST_CODE = 200;
    private ImageView imageView;
    private Bitmap originalImage;
    private Bitmap currentImage;
    private Stack<Bitmap> undoStack = new Stack<>();
    private Stack<Bitmap> redoStack = new Stack<>();
    private Path currentPath;
    private Paint pathPaint;
    private boolean isPath;
    private String imagePath;
    private Uri imageUri;

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case READ_REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] != PERMISSION_GRANTED) {
                    Toast.makeText(this, "Read permission is required!", Toast.LENGTH_LONG).show();
                } else {
                    GetImage();
                }
                break;
            default:
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crop);

        imageView = findViewById(R.id.imageView);
        ImageButton BackButton = findViewById(R.id.back_image_button);
        ImageButton UndoButton = findViewById(R.id.undo_image_button);
        ImageButton RedoButton = findViewById(R.id.redo_image_button);
        ImageButton NextButton = findViewById(R.id.next_image_button);

        GetImage();

        pathPaint = new Paint();
        pathPaint.setAntiAlias(true);
        pathPaint.setStyle(Paint.Style.STROKE);
        pathPaint.setStrokeWidth(5);
        pathPaint.setColor(Color.RED);

        //返回按钮的具体实现
        BackButton.setOnClickListener(v -> {
            Intent intent_back = new Intent(CropActivity.this, CamActivity.class);
            startActivity(intent_back);
            finish();
        });

        //向前撤销按钮的具体实现
        UndoButton.setOnClickListener(v -> {
            if (!undoStack.isEmpty()) {
                redoStack.push(currentImage);
                currentImage = undoStack.pop();
                imageView.setImageBitmap(currentImage);
            }
        });

        //向后撤销按钮的具体实现
        RedoButton.setOnClickListener(v -> {
            if (!redoStack.isEmpty()) {
                undoStack.push(currentImage);
                currentImage = redoStack.pop();
                imageView.setImageBitmap(currentImage);
            }
        });

        //下一步按钮的具体实现
        NextButton.setOnClickListener(v -> {
            File croppedImageFile = saveBitmapToFile(currentImage);
            if (croppedImageFile != null) {
                Intent calculateIntent = new Intent(CropActivity.this, Calculate.class);
                calculateIntent.putExtra("cropped_image_path", croppedImageFile.getAbsolutePath());

                calculateIntent.putExtra("isPath", isPath);
                if (isPath) {
                    calculateIntent.putExtra("original_image_path", imagePath);
                } else {
                    calculateIntent.putExtra("original_image_uri", imageUri);
                }
                startService(calculateIntent);
            }
        });

        //自由裁切的具体实现
        imageView.setOnTouchListener((v, event) -> {
            float[] realCoordinates = getBitmapPositionInsideImageView(imageView, event);
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    currentPath = new Path();
                    currentPath.moveTo(realCoordinates[0], realCoordinates[1]);
                    break;
                case MotionEvent.ACTION_MOVE:
                    currentPath.lineTo(realCoordinates[0], realCoordinates[1]);
                    break;
                case MotionEvent.ACTION_UP:
                    new ApplyCropTask().execute(currentPath);
                    break;
            }
            redrawImage();
            return true;
        });
    }

    private float[] getBitmapPositionInsideImageView(ImageView imageView, MotionEvent event) {
        float[] ret = new float[2];
        if (imageView == null || imageView.getDrawable() == null)
            return ret;

        // Get image matrix values and place them in an array
        float[] f = new float[9];
        imageView.getImageMatrix().getValues(f);

        // Extract the scale values using the constants
        final float scaleX = f[Matrix.MSCALE_X];
        final float scaleY = f[Matrix.MSCALE_Y];

        // Calculate the real image coordinates
        ret[0] = (event.getX() - f[Matrix.MTRANS_X]) / scaleX;
        ret[1] = (event.getY() - f[Matrix.MTRANS_Y]) / scaleY;

        return ret;
    }


    private void redrawImage() {
        Bitmap tempBitmap = currentImage.copy(currentImage.getConfig(), true);
        Canvas canvas = new Canvas(tempBitmap);
        canvas.drawPath(currentPath, pathPaint);
        imageView.setImageBitmap(tempBitmap);
    }

    private class ApplyCropTask extends AsyncTask<Path, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(Path... paths) {
            Path path = paths[0];
            Bitmap resultBitmap = Bitmap.createBitmap(currentImage.getWidth(), currentImage.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(resultBitmap);

            Paint pathFillPaint = new Paint();
            pathFillPaint.setAntiAlias(true);
            pathFillPaint.setColor(Color.WHITE);
            pathFillPaint.setStyle(Paint.Style.FILL);
            canvas.drawPath(path, pathFillPaint);

            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(currentImage, 0, 0, paint);

            return resultBitmap;
        }

        @Override
        protected void onPostExecute(Bitmap resultBitmap) {
            undoStack.push(currentImage);
            redoStack.clear();
            currentImage = resultBitmap;
            imageView.setImageBitmap(currentImage);

        }
    }

    private void GetImage(){
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, READ_REQUEST_CODE);
            return;
        }

        Intent intent = getIntent();
        isPath = intent.getBooleanExtra("isPath", true);

        if (isPath) {
            imagePath = intent.getStringExtra("image_path");
            if (imagePath != null) {
                originalImage = BitmapFactory.decodeFile(imagePath);
            }
        } else {
            imageUri = Uri.parse(intent.getStringExtra("image_uri"));
            if (imageUri != null) {
                InputStream inputStream = null;
                try {
                    inputStream = getContentResolver().openInputStream(imageUri);
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                }
                originalImage = BitmapFactory.decodeStream(inputStream);
            }
        }

        if (originalImage != null) {
            currentImage = originalImage.copy(originalImage.getConfig(), true);
            imageView.setImageBitmap(currentImage);  // 确保将Bitmap设置到ImageView中
        } else {
            Toast.makeText(this, "Cannot load image", Toast.LENGTH_SHORT).show();
            Intent intent_back = new Intent(CropActivity.this, CamActivity.class);
            startActivity(intent_back);
            finish();  // 关闭当前的Activity
        }
    }

    private File saveBitmapToFile(Bitmap bitmap) {
        try {
            File outputDir = getCacheDir();
            Log.i("myLog", outputDir.toString());
            File outputFile = File.createTempFile("cropped_image", ".png", outputDir);
            try (FileOutputStream out = new FileOutputStream(outputFile)) {
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            }
            return outputFile;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}